package com.ZeroCarbon.service.impl;

import com.ZeroCarbon.domain.dto.GoodsPreviewDTO;
import com.ZeroCarbon.domain.po.Cart;
import com.ZeroCarbon.domain.po.Good;
import com.ZeroCarbon.domain.po.Identity;
import com.ZeroCarbon.exception.BusinessLogicException;
import com.ZeroCarbon.mapper.CartMapper;
import com.ZeroCarbon.service.ICartService;
import com.ZeroCarbon.utils.UserHolder;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.baomidou.mybatisplus.extension.toolkit.Db;
import org.springframework.stereotype.Service;

import java.util.Collections;
import java.util.List;
import java.util.stream.Collectors;

import static com.ZeroCarbon.exception.BusinessLogicException.BUSY_EXCEPTION;
import static com.ZeroCarbon.exception.BusinessLogicException.ERROR_EXCEPTION;

@Service
public class CartServiceImpl extends ServiceImpl<CartMapper, Cart> implements ICartService {

    /**
     * 添加商品到购物车
     */
    @Override
    public void addGoodToCart(String id) throws BusinessLogicException {
        //获取用户id
        String userId = UserHolder.getUser();
        //创建购物车对象
        Cart cart = new Cart(userId, id);
        try {
            //保存到购物车
            if (!save(cart)) {
                throw new BusinessLogicException();
            }
        } catch (Exception e) {
            throw new BusinessLogicException(BUSY_EXCEPTION);
        }
    }

    /**
     * 从购物车获取商品
     */
    @Override
    public List<GoodsPreviewDTO> getGoodsFromCart() throws BusinessLogicException {
        //获取用户id
        String userId = UserHolder.getUser();
        //获取商品id构造器
        LambdaQueryWrapper<Cart> goodsWrapper = new LambdaQueryWrapper<Cart>()
                .select(Cart::getGoodsId)
                .eq(Cart::getId, userId);
        //获取用户购物车列表
        List<Cart> carts;
        try {
            carts = list(goodsWrapper);
        } catch (Exception e) {
            throw new BusinessLogicException(ERROR_EXCEPTION);
        }
        //如果为空则返回空集合
        if (carts.isEmpty()) {
            return Collections.emptyList();
        }
        //处理数据
        return carts.stream()
                .map(cart -> {
                    //商品信息对象
                    GoodsPreviewDTO goodsPreviewDTO;
                    //身份信息
                    Identity identity;
                    try {
                        //获取购物车其中商品的id
                        String goodsId = cart.getGoodsId();
                        //获取商品
                        Good good = Db.lambdaQuery(Good.class)
                                .eq(Good::getId, goodsId)
                                .one();
                        //转化对象
                        goodsPreviewDTO = good.toGoodsPreviewDTO();
                        //获取发布身份
                        identity = Db.lambdaQuery(Identity.class)
                                .eq(Identity::getId, good.getIdentityId())
                                .one();
                    } catch (Exception e) {
                        //lambda内的异常需要非受检类型的，lambda表达式必须匹配函数式接口的抽象方法签名
                        throw new RuntimeException(ERROR_EXCEPTION);
                    }
                    //设置身份
                    if (identity != null) {
                        goodsPreviewDTO.setIdentity(identity.getName());
                    }
                    return goodsPreviewDTO;
                }).collect(Collectors.toList());
    }

    /**
     * 从购物车删除
     *
     * @param id 商品id
     */
    @Override
    public void deleteGoodFromCart(String id) throws BusinessLogicException {
        //获取用户id
        String userId = UserHolder.getUser();
        //购物车构造器
        LambdaQueryWrapper<Cart> cartWrapper = new LambdaQueryWrapper<Cart>()
                .eq(Cart::getId, userId)
                .eq(Cart::getGoodsId, id);
        try {
            //移除相关产品项
            if (!remove(cartWrapper)) {
                throw new BusinessLogicException();
            }
        } catch (Exception e) {
            throw new BusinessLogicException(ERROR_EXCEPTION);
        }
    }
}
